#ifndef NOTIFY_NOTIFYMANAGER_H
#define NOTIFY_NOTIFYMANAGER_H

#include <QList>
#include <QMutex>
#include <QObject>


namespace Converse {
class AbstractMessage;
class TextMessage;
class PhotoMessage;
class VoiceMessage;
}

namespace Account {
class Buddy;
}

namespace Notify {

class Notification;
class TextMessageNotification;
class OnlineStatusNotification;

class Manager : public QObject
{
    Q_OBJECT
public:
    typedef QList<Notification *> NotificationList;

private:
    Manager(QObject *parent = 0);

private:
    static Manager *m_instance;

private:
    mutable QMutex m_mutex;
    NotificationList m_notificationList;

Q_SIGNALS:
    void notificationAboutToBeAppended(Notification *notification);
    void notificationAppended(Notification *notification);
    void notificationAboutToBeRemoved(Notification *notification);
    void notificationRemoved(Notification *notification);

    void dataEmpty();
    void dataCleared();

private:
    void setConnection() const;

private:
    TextMessageNotification *createTextMessageNotification(Converse::TextMessage *message);
    OnlineStatusNotification *createStatusNotification(Account::Buddy *buddy);

private:
    void itemAboutToBeAppended(Notification *notification);
    void itemAppended(Notification *notification);
    void itemAboutToBeRemoved(Notification *notification);
    void itemRemoved(Notification *notification);

private slots:
    void onMessageReceived(Converse::AbstractMessage *message);
    void onOnlineStatusChanged(Account::Buddy *buddy);
    void onNotificationTimeout();

public:
    static Manager *instance();

public:
    inline const NotificationList &notificationList() const {
        return m_notificationList;
    }

public:
    void append(Notification *notification);
    void remove(Notification *notification);
    void remove(int index);
    void removeFirstItem();

public:
    bool contains(Notification *notification) const;
    int count() const;
    int size() const;

public:
    Notification *at(int index) const;
    int indexOf(Notification *notification) const;
    void clearData();

public Q_SLOTS:
    void onCloseItem(Notification *notification);
    void onNotificationWidgetAboutToBeClosed();
};

} // namespace Notify

#endif // NOTIFY_NOTIFYMANAGER_H
